﻿#include "pch.h"
#include "framework.h"

#include "magic_enum/magic_enum.hpp"
#include "Format.h"

#include <atlstr.h>
#include "resource.h"
#include <comutil.h>
#include <regex>

#pragma comment(lib, "comsuppw.lib")

#pragma comment(lib , "User32.lib")
std::string wstring2string(const std::wstring& ws);

std::wstring to_wide_string(std::string wstr);

#define ReplaceN(str) regex_replace(str, std::regex("\\n"),"\n")

void ShowError(
	ErrorCode Code,
	std::string ErrorMessage,

	bool WriteLog
) {
	//对enum解码成string
	auto CodeStringView = magic_enum::enum_name(Code);
	std::string CodeString{ CodeStringView };

	//开始拼装错误信息

	/*
	// 程序发生错误。该错误可能不会影响程序运行，您可以继续运行但某一操作被终
	// 止，也可能是在报告错误后关闭程序，并给出不正常的退出代码（如“退出代码1”）
	std::string Text = "The program encountered an error. This error may not affect the program's operation. You can continue running but a certain operation is terminated, or it may be closing the program after reporting an error and giving an abnormal exit code (such as \"Exit Code 1\")\n";

	// 错误代码： (代码)
	Text += "\nErrorCode:" + CodeString + "\n\n";

	// (错误信息)
	Text += ErrorMessage + "\n\n";

	//是否写入日志
	if (!LogProtocol::CheckLogServiceInitStatus() && WriteLog)
	{
		//Text += "未将此错误信息写入日志，因为日志服务未开启。";
		Text += "This error message was not written to the log because the logging service is not turned on.";
	}
	else if (!WriteLog)
	{
		//Text += "未将此错误信息写入日志。";
		Text += "This error message was not written to the log.";
	}
	*/
	CString cs;
	cs.LoadStringW(ERR_INFO);
	//std::string Text = regex_replace(util::Format(wstring2string(cs.GetBuffer()), CodeString, ErrorMessage), std::regex("\\n"),"\n")
	std::string Text = ReplaceN(util::Format(wstring2string(cs.GetBuffer()),CodeString,ErrorMessage));

	if (LogProtocol::CheckLogServiceInitStatus() && WriteLog) {
		cs.LoadStringW(LOG_ERRINFO_1);
		LogProtocol::WriteLog::Error(ReplaceN(wstring2string(cs.GetBuffer())));
		cs.LoadStringW(LOG_ERRINFO_2);
		//LogProtocol::WriteLog::Error("Error Code:    " + CodeString);
		LogProtocol::WriteLog::Error(ReplaceN(util::Format(wstring2string(cs.GetBuffer()), CodeString)));
		//LogProtocol::WriteLog::Error("Error Info:    " + ErrorMessage);
		cs.LoadStringW(LOG_ERRINFO_3);
		LogProtocol::WriteLog::Error(ReplaceN(util::Format(wstring2string(cs.GetBuffer()),ErrorMessage)));
		LogProtocol::WriteLog::Error("!!!!!!!!!!!!!!!!!!!!");
	}
	cs.LoadStringW(ERR_TITLE);
	//显示信息框
	MessageBoxW(
		NULL,
		to_wide_string(Text).c_str(),
		cs,
		MB_OK | MB_ICONERROR
	);

}


void RealEmergencyExit(
	int ExitCode, 
	std::string Source, int Line
) {
	CString cs;
	cs.LoadStringW(E_EXIT_1);
	LogProtocol::WriteLog::Warning("Program execution emergency exit task, exit code:" + std::to_string(ExitCode));

#ifdef _DEBUG
	LogProtocol::WriteLog::Debug("Initiate Sources File:" + Source + "    Line:" + std::to_string(Line));
#endif

	LogProtocol::StopLogService();
	exit(ExitCode);
}

std::wstring to_wide_string(std::string wstr)
{
	std::wstring res;
	int len = MultiByteToWideChar(CP_ACP, 0, wstr.c_str(), wstr.size(), nullptr, 0);
	if (len < 0) {
		return res;
	}
	wchar_t* buffer = new wchar_t[len + 1];
	if (buffer == nullptr) {
		return res;
	}
	MultiByteToWideChar(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len);
	buffer[len] = '\0';
	res.append(buffer);
	delete[] buffer;
	return res;
}

std::string wstring2string(const std::wstring& ws)
{
	_bstr_t t = ws.c_str();
	char* pchar = (char*)t;
	std::string result = pchar;
	return result;
}